<#ftl ns_prefixes={"orm": "http://java.sun.com/xml/ns/persistence/orm"}
	encoding="UTF-8" />
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<#compress>
<#recurse doc>
<#macro "orm:entity-mappings"><#-- 处理节点：orm:entity-mappings -->
	<#global selectChunk = 3 />
	<#global updateChunk = 2 />
	<#global class = .node["orm:entity"].@class />
	<#global package = .node["orm:package"] />
	<#global tabAfa = "${class}"[0]?upper_case>
	<#global prefix = "${class}"[0..2]?upper_case>
	<#global table = .node["orm:entity"]["orm:table"].@name />
	<@prepareLists attrs=.node["orm:entity"]["orm:attributes"] />
</#macro>
<#macro prepareLists attrs><#-- 处理节点的属性 -->
	<#global id = attrs["orm:id"].@name />
	<#global idCol = attrs["orm:id"]["orm:column"].@name />
	<#local attributesString><#list attrs["orm:basic"] as n>${n.@name}<#if n_has_next>,</#if></#list></#local>
	<#global attributes = attributesString?split(",") />
	<#local columnsString><#list attrs["orm:basic"]["orm:column"] as n>${n.@name}<#if n_has_next>,</#if></#list></#local>
	<#global columns = columnsString?split(",") />
</#macro>
<#macro @element> <#-- 所有没有定义匹配的节点到这里处理 -->
</#macro>
</#compress>
<sqlMap namespace="${package}.${class}">
	<typeAlias alias="${class}" type="${package}.${class}" />

	<!-- originMap -->
	<resultMap class="${class}" id="originMap"><#if id?has_content && idCol?has_content>
		<result column="${idCol}" property="${id}" /></#if><#list attributes as atrs>
		<result column="${columns[atrs_index]}" property="${atrs}" /></#list>
	</resultMap>

	<!-- entityMap -->
	<resultMap class="${class}" id="entityMap"><#if id?has_content && idCol?has_content>
		<result column="${prefix}_${idCol}" property="${id}" /></#if><#list attributes as atrs>
		<result column="${prefix}_${columns[atrs_index]}" property="${atrs}" /></#list>
	</resultMap>

	<!-- default insert statement -->
	<insert id="insert"><![CDATA[
		INSERT INTO ${table}(<#list columns as col>
			${col}<#if col_has_next>, </#if></#list>
		)VALUES(<#list attributes as attr>
			#${attr}#<#if attr_has_next>,</#if></#list>
		)]]><#if id?has_content && idCol?has_content>
		<selectKey resultClass="int" keyProperty="${id}">
        	<![CDATA[ SELECT LAST_INSERT_ID() AS ${idCol} ]]>
		</selectKey></#if>
	</insert>

	<!-- update and delete condition -->
	<sql id="updateAndDeleteConditionStmt">
		<isNotEmpty property="conditionSet">
			<#if id?has_content && idCol?has_content>
				<isNotEmpty property="conditionSet.${id}" prepend="AND">
					${idCol} = #conditionSet.${id}#
				</isNotEmpty>
				<isNotEmpty property="conditionSet.${id}s">
					<iterate property="conditionSet.${id}s" open="(" close=")"
						conjunction="OR" prepend="AND">
						${idCol} = #conditionSet.${id}s[]#
					</iterate>
				</isNotEmpty>
			</#if>
		</isNotEmpty>
	</sql>

	<!-- default update statement -->
	<update id="update"><![CDATA[
		UPDATE ${table} SET <#if id?has_content && idCol?has_content>
			${idCol} = #entity.${id}#,</#if><#list columns as col>
			${col} = #entity.${attributes[col_index]}#<#if col_has_next>,</#if></#list>]]>
		<dynamic prepend="WHERE"><#if id?has_content && idCol?has_content>
			<isEmpty property="conditionSet" prepend="AND">
				${idCol} = #entity.${id}#
			</isEmpty></#if>
			<include refid="updateAndDeleteConditionStmt" />
		</dynamic>
	</update>

	<!-- delete -->
	<delete id="delete">
		<![CDATA[ DELETE FROM ${table} ]]>
		<dynamic prepend="WHERE">
			<isEmpty property="conditionSet">
				1 = 2
			</isEmpty>
			<include refid="updateAndDeleteConditionStmt" />
		</dynamic>
	</delete>

	<!-- default columns sql fragment -->
	<sql id="selectColumns"><![CDATA[<#if idCol?has_content>
		${tabAfa}.${idCol} AS ${prefix}_${idCol},</#if><#list columns as col>
		${tabAfa}.${col} AS ${prefix}_${col}<#if col_has_next>,</#if></#list>
	]]></sql>

	<!-- default query from -->
	<sql id="queryFromStmt"><![CDATA[
		FROM ${table} ${tabAfa}
	]]></sql>

	<!-- default query condition -->
	<sql id="selectConditionStmt">
		<dynamic prepend="WHERE">
			<isNotEmpty property="conditionSet"><#if id?has_content && idCol?has_content>
				<isNotEmpty property="conditionSet.${id}" prepend="AND">
					${tabAfa}.${idCol} = #conditionSet.${id}#
				</isNotEmpty></#if>
			</isNotEmpty>
		</dynamic>
	</sql>

	<!-- default result order -->
	<sql id="queryOrderStmt">
		<dynamic prepend="ORDER BY">
			<isNotEmpty property="queryOrder">
				<iterate conjunction="," property="queryOrder">
					<isEqual property="queryOrder[].ascending"
						compareValue="true">
						${tabAfa}.$queryOrder[].property$ asc
					</isEqual>
					<isEqual property="queryOrder[].ascending"
						compareValue="false">
						${tabAfa}.$queryOrder[].property$ desc
					</isEqual>
				</iterate>
			</isNotEmpty>
		</dynamic>
	</sql>

	<!-- get -->
	<select id="get" resultMap="entityMap">
		SELECT <include refid="selectColumns" />
		<![CDATA[
		FROM ${table} ${tabAfa}
		]]>
		<include refid="selectConditionStmt" />
	</select>

	<!-- default query count -->
	<select id="queryCount" resultClass="int">
		<@constraintsFragment count=true />
	</select>

	<!-- query -->
	<select id="query" resultMap="entityMap">
		<@constraintsFragment count=false />
	</select>
</sqlMap>
<#macro constraintsFragment count=false page=false>
		<#if count>SELECT COUNT(*)<#else>SELECT <include refid="selectColumns" /></#if>
		<include refid="queryFromStmt" />
		<include refid="selectConditionStmt" /><#if !count>
		<include refid="queryOrderStmt" />
		<dynamic>
			<!-- 分页：当页起始记录 -->
			<isNotEmpty property="pagedStart">
				<!-- 分页：当页结束记录 -->
				LIMIT #pagedStart#, #pagedSize#
			</isNotEmpty>
		</dynamic></#if>
</#macro>
